
#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h>
#include <Psapi.h>

void EnablePriv();
void print_size(ULONGLONG size);

int main()
{
    printf("进程名称");
    printf("\t进程ID");
    printf("\tPageFaultCount");
    printf("\tPeakWorkingSetSize");
    printf("\tWorkingSetSize");
    printf("\tQuotaPeakPagedPoolUsage");
    printf("\tQuotaPagedPoolUsage");
    printf("\tQuotaPeakNonPagedPoolUsage");
    printf("\tQuotaNonPagedPoolUsage");
    printf("\tPagefileUsage");
    printf("\tPeakPagefileUsage\n");
    EnablePriv();
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    OSVERSIONINFOW osinfo;
    GetVersionExW(&osinfo);
    DWORD flag = osinfo.dwMajorVersion >= 6 ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION;

    if (INVALID_HANDLE_VALUE == hProcessSnap)
        return;

    PROCESSENTRY32W pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32W);

    if(Process32FirstW(hProcessSnap, &pe32)) do
    {
        DWORD pid = pe32.th32ProcessID;
        printf("%S\t%lu", pe32.szExeFile, pid);

        if (!pid)
        {
            putchar('\n');
            continue;
        }

        HANDLE hProcess = OpenProcess(flag, FALSE, pid);
        PROCESS_MEMORY_COUNTERS pmc;
        pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
        if (GetProcessMemoryInfo(hProcess, &pmc, sizeof pmc))
        {
            putchar('\t'); print_size(pmc.PageFaultCount);
            putchar('\t'); print_size(pmc.PeakWorkingSetSize);
            putchar('\t'); print_size(pmc.WorkingSetSize);
            putchar('\t'); print_size(pmc.QuotaPeakPagedPoolUsage);
            putchar('\t'); print_size(pmc.QuotaPagedPoolUsage);
            putchar('\t'); print_size(pmc.QuotaPeakNonPagedPoolUsage);
            putchar('\t'); print_size(pmc.QuotaNonPagedPoolUsage);
            putchar('\t'); print_size(pmc.PagefileUsage);
            putchar('\t'); print_size(pmc.PeakPagefileUsage);
        }

        putchar('\n');

        CloseHandle(hProcess);
    } while (Process32NextW(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    return 0;
}

void EnablePriv()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);
    LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid ); //修改进程权限
    tkp.PrivilegeCount=1;
    tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof tkp,NULL,NULL); //通知系统修改进程权限
    CloseHandle(hToken);
}

void print_size(ULONGLONG size)
{
    double dsize = size;
    if(size < 0x400)
    {
        printf("%llu B", size);
        return;
    }
    const char *pre = "KMGTPE";
    for (size_t i = 0; i < 6; i++)
    {
        dsize /= 0x400;
        if(i == 5 || dsize < 0x400)
        {
            printf("%.1f %cB", dsize, pre[i]);
            break;
        }
    }
}